package com.moshang.blog.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.moshang.blog.entity.SysMenu;
import com.moshang.blog.entity.SysRoleMenu;
import com.moshang.blog.entity.vo.ShowMenu;
import com.moshang.blog.mapper.SysMenuMapper;
import com.moshang.blog.mapper.SysRoleMenuMapper;
import com.moshang.blog.core.utils.TreeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;


import com.moshang.blog.service.SysMenuService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author moshang
 */
@Service("sysResourcesService")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {


    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private SysRoleMenuMapper roleMenuMapper;
    @Override
    public List<SysMenu> getResourcesByUserId(Integer id) {
        return sysMenuMapper.getSysMenuByUserId(id);
    }

    @Override
    public JSONArray getSysMenuByUserId(List<SysMenu> menuList) {
        JSONArray jsonArr = new JSONArray();
        Collections.sort(menuList, (o1, o2) -> {
            if (o1.getSort() == null || o2.getSort() == null) {
                return -1;
            }
            if (o1.getSort() > o2.getSort()) {
                return 1;
            }
            if (o1.getSort().equals(o2.getSort())) {
                return 0;
            }
            return -1;
        });
        int pNum = 1000;
        for (SysMenu menu : menuList) {
            if (menu.getParentId()==null) {
                SysMenu resourcesEntity = getChilds(menu, pNum, 0, menuList);
                jsonArr.add(resourcesEntity);
                pNum += 1000;
            }
        }
        return jsonArr;
    }

    @Override
    public List<ShowMenu> getShowMenuByUserId(Integer userId) {
        Map<String,Object> map = Maps.newHashMap();
        map.put("userId",userId);
        map.put("parentId",null);
        return baseMapper.selectShowMenuByUser(map);
    }
    @Cacheable(value = "allMenus",key = "'allMenus_isShow_'+#map['isShow'].toString()",unless = "#result == null or #result.size() == 0")
    @Override
    public List<SysMenu> selectAllMenus(Map<String, Object> map) {
        return baseMapper.getMenus(map);
    }

    @Override
    public int getCountByName(String name) {
        QueryWrapper<SysMenu> wrapper = new QueryWrapper<>();
        wrapper.eq("is_activited",0);
        wrapper.eq("name",name);
        return baseMapper.selectCount(wrapper);
    }

    @Override
    public int getCountByPermission(String permission) {
        QueryWrapper<SysMenu> wrapper = new QueryWrapper<>();
        wrapper.eq("is_activited",0);
        wrapper.eq("permission",permission);
        return baseMapper.selectCount(wrapper);
    }
    @Caching(evict = {
            @CacheEvict(value = "allMenus",allEntries = true),
            @CacheEvict(value = "user",allEntries = true)
    })
    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)

    public void saveOrUpdateMenu(SysMenu menu) {
        saveOrUpdate(menu);
    }

    @Override
    public JSONArray getTreeUtil(Long roleId) {
        TreeUtil treeUtil = null;
        QueryWrapper<SysMenu> entity = new QueryWrapper<SysMenu>();
        entity.eq("is_activited",0);
        List<SysMenu> sysMenus = baseMapper.selectList(entity);
        List<SysMenu> supers = sysMenus.stream().filter(sysMenu ->
                sysMenu.getParentId()==null)
                .collect(Collectors.toList());
        sysMenus.removeAll(supers);
        supers.sort(Comparator.comparingInt(SysMenu::getSort));
        JSONArray jsonArr = new JSONArray();
        for (SysMenu sysMenu : supers) {
            treeUtil = getChildByTree(sysMenu, sysMenus, 0, null, roleId);
            jsonArr.add(treeUtil);
        }
        return jsonArr;
    }

    public SysMenu getChilds(SysMenu menu, int pNum, int num, List<SysMenu> menuList) {
        for (SysMenu sysMenu: menuList) {
            if (sysMenu.getId().equals(sysMenu.getParentId()) ) {
                ++num;
                SysMenu m = getChilds(sysMenu, pNum, num, menuList);
                m.setSort(pNum + num);
                menu.addChild(m);
            }
        }
        return menu;

    }


    public TreeUtil getChildByTree(SysMenu sysMenu, List<SysMenu> sysMenus, int layer, Integer pId, Long roleId) {
        layer++;
        TreeUtil treeUtil = new TreeUtil();
        List<SysMenu> childSysMenu = sysMenus.stream().filter(s ->
                s.getParentId()==sysMenu.getId()).collect(Collectors.toList());
            sysMenus.removeAll(childSysMenu);
        treeUtil.setId(sysMenu.getId().toString());
        treeUtil.setName(sysMenu.getName());
        treeUtil.setLayer(layer);
        if (pId!=null){
            treeUtil.setPId(pId.toString());
        }
        /**判断是否存在*/
        if (roleId!=null) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(sysMenu.getId());
            sysRoleMenu.setRoleId(roleId.intValue());
            int count = roleMenuMapper.selectCountByCondition(sysRoleMenu);
            if (count > 0) {
                treeUtil.setChecked(true);
            }

        }
        for (SysMenu menu : childSysMenu) {
            TreeUtil m = getChildByTree(menu, sysMenus, layer, menu.getId(), roleId);
            treeUtil.getChildren().add(m);
        }
        return treeUtil;
    }
}
